/*
 * @Author: Du Weixing duweixing@sgsimulation.com
 * @Date: 2024-10-19 18:51:57
 * @LastEditors: Du Weixing duweixing@sgsimulation.com
 * @LastEditTime: 2024-12-05 09:44:11
 * @FilePath: \SGFEM\Solver\SectionCalculator\BeamSection\FormulaMethod\test\RodBeamSectionFormulaCalculatorTest.hpp
 * @Description: 
 * 
 * Copyright (c) 2024 by 神工仿真, All Rights Reserved. 
 */

#pragma once
#include "gtest/gtest.h"
#include "DataStructure/Common/Real.h"
#include "DataStructure/Input/Property/BeamSectionStandardTypes.h"
#include "../Interface/BeamSectionFormulaCalculatorFactory.h"
#include "../Beam/RodBeamSectionFormulaCalculator.h"

using SG::DataStructure::Common::Real;
using namespace SG::DataStructure::FEM;
using SG::FEMSolver::Element::BeamSectionFormulaCalculatorFactory;
using SG::FEMSolver::Element::RodBeamSectionFormulaCalculator;

// 将 BeamSectionFormulaCalculatorFactory 生成对象测试放置在具体截面属性计算中
TEST (BeamSectionFormulaCalculatorFactoryTest, RodSectionCalculatorCreate)
{
    // Test data
    auto calculatorPtr = BeamSectionFormulaCalculatorFactory::Create (BeamSectionStandardTypes::BEAMSECTYPE_ROD);
    auto rodCalculatorPtr = dynamic_cast<RodBeamSectionFormulaCalculator*> (calculatorPtr.get ());

    // Check
    ASSERT_TRUE (nullptr != rodCalculatorPtr);
}

// PBEAML-ROD 恒截面属性计算测试
TEST (BeamSectionFormulaCalculatorTest, RodSection)
{
    // Input data
    PBEAMLData pBeamL;
    pBeamL.m_id  = 2;
    pBeamL.m_mId = 3;
    pBeamL.SetGroup ("MSCBML0");
    pBeamL.SetBeamSectionStandardTypes (BeamSectionStandardTypes::BEAMSECTYPE_ROD);
    pBeamL.m_section = {{1.0, 0.0, 10.0, {2.5}}, {1.0, 1.0, 10.0, {2.5}}};

    // Test data
    RodBeamSectionFormulaCalculator calculator;
    auto pBeamTest = calculator.Compute (pBeamL);

    // Target data
    PBEAMData pBeamTarget;
    pBeamTarget.m_id    = 2;
    pBeamTarget.m_mId   = 3;
    pBeamTarget.m_nsges = 1;
    pBeamTarget.m_ccf   = 1;

    Real SO[11] {1.000000, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.000000};
    Real XXB[11]{0.000000, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.000000};
    Real A[11]  {19.63495, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 19.63495};
    Real I1[11] {30.67962, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 30.67962};
    Real I2[11] {30.67962, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 30.67962};
    Real J[11]  {61.35923, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 61.35923};
    Real NSM[11]{10.00000, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.00000};
    std::memcpy (pBeamTarget.m_SO,  SO,  sizeof (SO));
    std::memcpy (pBeamTarget.m_XXB, XXB, sizeof (XXB));
    std::memcpy (pBeamTarget.m_A,   A,   sizeof (A));
    std::memcpy (pBeamTarget.m_I1,  I1,  sizeof (I1));
    std::memcpy (pBeamTarget.m_I2,  I2,  sizeof (I2));
    std::memcpy (pBeamTarget.m_J,   J,   sizeof (J));
    std::memcpy (pBeamTarget.m_NSM, NSM, sizeof (NSM));

    Real C1[11]{ 2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,  2.5};
    Real D2[11]{ 2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,  2.5};
    Real E1[11]{-2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.5};
    Real F2[11]{-2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.5};
    std::memcpy (pBeamTarget.m_C1, C1, sizeof (C1));
    std::memcpy (pBeamTarget.m_D2, D2, sizeof (D2));
    std::memcpy (pBeamTarget.m_E1, E1, sizeof (E1));
    std::memcpy (pBeamTarget.m_F2, F2, sizeof (F2));

    pBeamTarget.m_K1 = 0.9;
    pBeamTarget.m_K2 = 0.9;

    // Check
    ASSERT_TRUE (pBeamTarget == pBeamTest);
}

// PBEAML-ROD 变截面（2 个）属性计算测试
TEST (BeamSectionFormulaCalculatorTest, 2VariableSections)
{
    // Input data
    PBEAMLData pBeamL;
    pBeamL.m_id  = 2;
    pBeamL.m_mId = 3;
    pBeamL.SetGroup ("MSCBML0");
    pBeamL.SetBeamSectionStandardTypes (BeamSectionStandardTypes::BEAMSECTYPE_ROD);
    pBeamL.m_section = {{1.0, 0.0, 10.0, {2.5}}, {1.0, 1.0, 10.0, {3.0}}, {1.0, 1.0, 10.0, {3.0}}};

    // Test data
    RodBeamSectionFormulaCalculator calculator;
    auto pBeamTest = calculator.Compute (pBeamL);

    // Target data
    PBEAMData pBeamTarget;
    pBeamTarget.m_id    = 2;
    pBeamTarget.m_mId   = 3;
    pBeamTarget.m_nsges = 1;
    pBeamTarget.m_ccf   = 2;

    Real SO[11] {1.000000, 1.000000, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.000000};
    Real XXB[11]{0.000000, 1.000000, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.000000};
    Real A[11]  {19.63495, 28.27433, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 28.27433};
    Real I1[11] {30.67962, 63.61725, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 63.61725};
    Real I2[11] {30.67962, 63.61725, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 63.61725};
    Real J[11]  {61.35923, 127.2345, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 127.2345};
    Real NSM[11]{10.00000, 10.00000, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.00000};
    std::memcpy (pBeamTarget.m_SO,  SO,  sizeof (SO));
    std::memcpy (pBeamTarget.m_XXB, XXB, sizeof (XXB));
    std::memcpy (pBeamTarget.m_A,   A,   sizeof (A));
    std::memcpy (pBeamTarget.m_I1,  I1,  sizeof (I1));
    std::memcpy (pBeamTarget.m_I2,  I2,  sizeof (I2));
    std::memcpy (pBeamTarget.m_J,   J,   sizeof (J));
    std::memcpy (pBeamTarget.m_NSM, NSM, sizeof (NSM));

    Real C1[11]{ 2.5,  3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,  3.0};
    Real D2[11]{ 2.5,  3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,  3.0};
    Real E1[11]{-2.5, -3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.0};
    Real F2[11]{-2.5, -3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.0};
    std::memcpy (pBeamTarget.m_C1, C1, sizeof (C1));
    std::memcpy (pBeamTarget.m_D2, D2, sizeof (D2));
    std::memcpy (pBeamTarget.m_E1, E1, sizeof (E1));
    std::memcpy (pBeamTarget.m_F2, F2, sizeof (F2));

    pBeamTarget.m_K1 = 0.9;
    pBeamTarget.m_K2 = 0.9;

    // Check
    ASSERT_TRUE (pBeamTarget == pBeamTest);
}

// PBEAML-ROD 变截面（3 个）属性计算测试
TEST (BeamSectionFormulaCalculatorTest, 3VariableSections)
{
    // Input data
    PBEAMLData pBeamL;
    pBeamL.m_id = 2;
    pBeamL.m_mId = 3;
    pBeamL.SetGroup ("MSCBML0");
    pBeamL.SetBeamSectionStandardTypes (BeamSectionStandardTypes::BEAMSECTYPE_ROD);
    pBeamL.m_section = {
        {1.0, 0.0, 10.0, {2.5}},
        {1.0, 0.5, 10.0, {3.0}},
        {1.0, 1.0, 10.0, {3.5}},
        {1.0, 1.0, 10.0, {3.5}}};

    // Test data
    RodBeamSectionFormulaCalculator calculator;
    auto pBeamTest = calculator.Compute (pBeamL);

    // Target data
    PBEAMData pBeamTarget;
    pBeamTarget.m_id    = 2;
    pBeamTarget.m_mId   = 3;
    pBeamTarget.m_nsges = 2;
    pBeamTarget.m_ccf   = 0;

    Real SO[11] {1.000000, 1.000000, 1.000000, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.000000};
    Real XXB[11]{0.000000, 0.500000, 1.000000, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.000000};
    Real A[11]  {19.63495, 28.27433, 38.48451, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 38.48451};
    Real I1[11] {30.67962, 63.61725, 117.8588, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 117.8588};
    Real I2[11] {30.67962, 63.61725, 117.8588, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 117.8588};
    Real J[11]  {61.35923, 127.2345, 235.7176, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 235.7176};
    Real NSM[11]{10.00000, 10.00000, 10.00000, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.00000};
    std::memcpy (pBeamTarget.m_SO,  SO,  sizeof (SO));
    std::memcpy (pBeamTarget.m_XXB, XXB, sizeof (XXB));
    std::memcpy (pBeamTarget.m_A,   A,   sizeof (A));
    std::memcpy (pBeamTarget.m_I1,  I1,  sizeof (I1));
    std::memcpy (pBeamTarget.m_I2,  I2,  sizeof (I2));
    std::memcpy (pBeamTarget.m_J,   J,   sizeof (J));
    std::memcpy (pBeamTarget.m_NSM, NSM, sizeof (NSM));

    Real C1[11]{ 2.5,  3.0,  3.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,  3.5};
    Real D2[11]{ 2.5,  3.0,  3.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,  3.5};
    Real E1[11]{-2.5, -3.0, -3.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.5};
    Real F2[11]{-2.5, -3.0, -3.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.5};
    std::memcpy (pBeamTarget.m_C1, C1, sizeof (C1));
    std::memcpy (pBeamTarget.m_D2, D2, sizeof (D2));
    std::memcpy (pBeamTarget.m_E1, E1, sizeof (E1));
    std::memcpy (pBeamTarget.m_F2, F2, sizeof (F2));

    pBeamTarget.m_K1 = 0.9;
    pBeamTarget.m_K2 = 0.9;

    // Check
    ASSERT_TRUE (pBeamTarget == pBeamTest);
}

// PBEAML-ROD 变截面（10 个）属性计算测试
TEST (BeamSectionFormulaCalculatorTest, 10VariableSections)
{
    // Input data
    PBEAMLData pBeamL;
    pBeamL.m_id  = 2;
    pBeamL.m_mId = 3;
    pBeamL.SetGroup ("MSCBML0");
    pBeamL.SetBeamSectionStandardTypes (BeamSectionStandardTypes::BEAMSECTYPE_ROD);
    pBeamL.m_section = {
        {1.0, 0.0, 10.0, {2.5}},
        {1.0, 0.1, 10.0, {3.0}},
        {1.0, 0.2, 10.0, {3.5}},
        {1.0, 0.3, 10.0, {4.0}},
        {1.0, 0.4, 10.0, {4.5}},
        {1.0, 0.5, 10.0, {5.0}},
        {1.0, 0.6, 10.0, {5.5}},
        {1.0, 0.7, 10.0, {6.0}},
        {1.0, 0.8, 10.0, {6.5}},
        {1.0, 1.0, 10.0, {7.5}},
        {1.0, 1.0, 10.0, {7.5}}};

    // Test data
    RodBeamSectionFormulaCalculator calculator;
    auto pBeamTest = calculator.Compute (pBeamL);

    // Target data
    PBEAMData pBeamTarget;
    pBeamTarget.m_id    = 2;
    pBeamTarget.m_mId   = 3;
    pBeamTarget.m_nsges = 9;
    pBeamTarget.m_ccf   = 0;

    Real SO[11] {1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000};
    Real XXB[11]{0.000000, 0.100000, 0.200000, 0.300000, 0.400000, 0.500000, 0.600000, 0.700000, 0.800000, 1.000000, 1.000000};
    Real A[11]  {19.63495, 28.27433, 38.48451, 50.26548, 63.61725, 78.53982, 95.03318, 113.0973, 132.7323, 176.7146, 176.7146};
    Real I1[11] {30.67962, 63.61725, 117.8588, 201.0619, 322.0623, 490.8739, 718.6884, 1017.876, 1401.985, 2485.049, 2485.049};
    Real I2[11] {30.67962, 63.61725, 117.8588, 201.0619, 322.0623, 490.8739, 718.6884, 1017.876, 1401.985, 2485.049, 2485.049};
    Real J[11]  {61.35923, 127.2345, 235.7176, 402.1239, 644.1247, 981.7477, 1437.377, 2035.752, 2803.970, 4970.098, 4970.098};
    Real NSM[11]{10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000};
    std::memcpy (pBeamTarget.m_SO,  SO,  sizeof (SO));
    std::memcpy (pBeamTarget.m_XXB, XXB, sizeof (XXB));
    std::memcpy (pBeamTarget.m_A,   A,   sizeof (A));
    std::memcpy (pBeamTarget.m_I1,  I1,  sizeof (I1));
    std::memcpy (pBeamTarget.m_I2,  I2,  sizeof (I2));
    std::memcpy (pBeamTarget.m_J,   J,   sizeof (J));
    std::memcpy (pBeamTarget.m_NSM, NSM, sizeof (NSM));

    Real C1[11]{ 2.5,  3.0,  3.5,  4.0,  4.5,  5.0,  5.5,  6.0,  6.5,  7.5,  7.5};
    Real D2[11]{ 2.5,  3.0,  3.5,  4.0,  4.5,  5.0,  5.5,  6.0,  6.5,  7.5,  7.5};
    Real E1[11]{-2.5, -3.0, -3.5, -4.0, -4.5, -5.0, -5.5, -6.0, -6.5, -7.5, -7.5};
    Real F2[11]{-2.5, -3.0, -3.5, -4.0, -4.5, -5.0, -5.5, -6.0, -6.5, -7.5, -7.5};
    std::memcpy (pBeamTarget.m_C1, C1, sizeof (C1));
    std::memcpy (pBeamTarget.m_D2, D2, sizeof (D2));
    std::memcpy (pBeamTarget.m_E1, E1, sizeof (E1));
    std::memcpy (pBeamTarget.m_F2, F2, sizeof (F2));

    pBeamTarget.m_K1 = 0.9;
    pBeamTarget.m_K2 = 0.9;

    // Check
    ASSERT_TRUE (pBeamTarget == pBeamTest);
}

// PBEAML-ROD 变截面（11 个）属性计算测试
TEST (BeamSectionFormulaCalculatorTest, 11VariableSections)
{
    // Input data
    PBEAMLData pBeamL;
    pBeamL.m_id  = 2;
    pBeamL.m_mId = 3;
    pBeamL.SetGroup ("MSCBML0");
    pBeamL.SetBeamSectionStandardTypes (BeamSectionStandardTypes::BEAMSECTYPE_ROD);
    pBeamL.m_section = {
        {1.0, 0.0, 10.0, {2.5}},
        {1.0, 0.1, 10.0, {3.0}},
        {1.0, 0.2, 10.0, {3.5}},
        {1.0, 0.3, 10.0, {4.0}},
        {1.0, 0.4, 10.0, {4.5}},
        {1.0, 0.5, 10.0, {5.0}},
        {1.0, 0.6, 10.0, {5.5}},
        {1.0, 0.7, 10.0, {6.0}},
        {1.0, 0.8, 10.0, {6.5}},
        {1.0, 0.9, 10.0, {7.0}},
        {1.0, 1.0, 10.0, {7.5}}};

    // Test data
    RodBeamSectionFormulaCalculator calculator;
    auto pBeamTest = calculator.Compute (pBeamL);

    // Target data
    PBEAMData pBeamTarget;
    pBeamTarget.m_id    = 2;
    pBeamTarget.m_mId   = 3;
    pBeamTarget.m_nsges = 10;
    pBeamTarget.m_ccf   = 0;

    Real SO[11] {1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000};
    Real XXB[11]{0.000000, 0.100000, 0.200000, 0.300000, 0.400000, 0.500000, 0.600000, 0.700000, 0.800000, 0.900000, 1.000000};
    Real A[11]  {19.63495, 28.27433, 38.48451, 50.26548, 63.61725, 78.53982, 95.03318, 113.0973, 132.7323, 153.9380, 176.7146};
    Real I1[11] {30.67962, 63.61725, 117.8588, 201.0619, 322.0623, 490.8739, 718.6884, 1017.876, 1401.985, 1885.741, 2485.049};
    Real I2[11] {30.67962, 63.61725, 117.8588, 201.0619, 322.0623, 490.8739, 718.6884, 1017.876, 1401.985, 1885.741, 2485.049};
    Real J[11]  {61.35923, 127.2345, 235.7176, 402.1239, 644.1247, 981.7477, 1437.377, 2035.752, 2803.970, 3771.482, 4970.098};
    Real NSM[11]{10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000, 10.00000};
    std::memcpy (pBeamTarget.m_SO,  SO,  sizeof (SO));
    std::memcpy (pBeamTarget.m_XXB, XXB, sizeof (XXB));
    std::memcpy (pBeamTarget.m_A,   A,   sizeof (A));
    std::memcpy (pBeamTarget.m_I1,  I1,  sizeof (I1));
    std::memcpy (pBeamTarget.m_I2,  I2,  sizeof (I2));
    std::memcpy (pBeamTarget.m_J,   J,   sizeof (J));
    std::memcpy (pBeamTarget.m_NSM, NSM, sizeof (NSM));

    Real C1[11]{ 2.5,  3.0,  3.5,  4.0,  4.5,  5.0,  5.5,  6.0,  6.5,  7.0,  7.5};
    Real D2[11]{ 2.5,  3.0,  3.5,  4.0,  4.5,  5.0,  5.5,  6.0,  6.5,  7.0,  7.5};
    Real E1[11]{-2.5, -3.0, -3.5, -4.0, -4.5, -5.0, -5.5, -6.0, -6.5, -7.0, -7.5};
    Real F2[11]{-2.5, -3.0, -3.5, -4.0, -4.5, -5.0, -5.5, -6.0, -6.5, -7.0, -7.5};
    std::memcpy (pBeamTarget.m_C1, C1, sizeof (C1));
    std::memcpy (pBeamTarget.m_D2, D2, sizeof (D2));
    std::memcpy (pBeamTarget.m_E1, E1, sizeof (E1));
    std::memcpy (pBeamTarget.m_F2, F2, sizeof (F2));

    pBeamTarget.m_K1 = 0.9;
    pBeamTarget.m_K2 = 0.9;

    // Check
    ASSERT_TRUE (pBeamTarget == pBeamTest);
}